﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using AutoTest.Common.Extension;
using AutoTest.Framework.Ioc;
using Microsoft.Extensions.DependencyInjection;

namespace AutoTest.Framework.Extensions
{
    /// <summary>
    /// 注册扩展服务
    /// </summary>
    public static class RegisterExtension
    {
        public static TService GetNamedService<TService>(this IServiceProvider serviceProvider, string serviceName)
        {
            var namedServiceProvider = serviceProvider.GetRequiredService<INamedServiceProvider>() ?? throw new ArgumentException($"Service \"{nameof(INamedServiceProvider)}\" is not registered in container");
            return namedServiceProvider.GetService<TService>(serviceName)!;
        }


        public static INamedServiceProviderBuilder AsNamedServiceProvider(this IServiceCollection services)
        {
            var builder = new NamedServiceProviderBuilder(services);
            return builder;
        }
        /// <summary>
        /// 批量注册
        /// </summary>
        /// <param name="services"></param>
        /// <param name="assembly"></param>
        /// <returns></returns>
        public static IServiceCollection RegsiterAssembly(this IServiceCollection services, Assembly assembly)
        {

            assembly.DefinedTypes.Where(t => typeof(ISingleton).IsAssignableFrom(t) && t.IsClass).Foreach(item =>
            {
                var interfaces = item.GetInterfaces();
                interfaces.Foreach(it =>
                {
                    if (it.FullName != typeof(ISingleton).FullName)
                    {
                        services.AddSingleton(it, item);
                    }
                });
            });

            assembly.DefinedTypes.Where(t => typeof(IScoped).IsAssignableFrom(t) && t.IsClass).Foreach(item =>
            {
                var interfaces = item.GetInterfaces();
                interfaces.Foreach(it =>
                {
                    if (it.FullName != typeof(IScoped).FullName)
                    {
                        services.AddScoped(it, item);
                    }
                });
            });
            assembly.DefinedTypes.Where(t => typeof(ITrasient).IsAssignableFrom(t) && t.IsClass).Foreach(item =>
            {
                var interfaces = item.GetInterfaces();
                interfaces.Foreach(it =>
                {
                    if (it.FullName != typeof(ITrasient).FullName)
                    {
                        services.AddTransient(it, item);
                    }
                });
            });
            return services;
        }

    }
}
